<template>
  <Codemirror :autofocus="true" :readOnly="true" v-model="codeValue" :style="codeStyle" :extensions="extensions" @ready="handleReady" @change="onChange"
    @focus="onFocus" @blur="onBlur" v-bind="$attrs" />
</template>

<script setup lang="ts">
import type { CSSProperties } from 'vue'
import { ref, watchEffect } from 'vue'
import { Codemirror } from 'vue-codemirror'
import { oneDark } from '@codemirror/theme-one-dark'

// language packages
import { javascript } from '@codemirror/lang-javascript'
import { json } from '@codemirror/lang-json'
import { css } from '@codemirror/lang-css'
import { sql } from '@codemirror/lang-sql'

//
interface Props {
  readonly?: boolean // 是否只读
  codeStyle?: CSSProperties // 代码样式 { width: '100%', height: '100%', fontSize: '16px' }
  dark?: boolean // 是否暗黑主题
  lang?: string // 代码语言
  code?: string // 代码字符串
  // placeholder?: string // 占位文本
  // autofocus?: boolean // 自动聚焦
  // disabled?: boolean // 禁用输入行为和更改状态
  // indentWithTab?: boolean // 启用 tab 按键
  // tabSize?: number // tab 按键缩进空格数
  // autoDestroy?: boolean // 组件销毁时是否自动销毁代码编辑器实例
}
const props = withDefaults(defineProps<Props>(), {
  codeStyle: () => ({}),
  dark: true,
  code: '',
  lang: 'javascript'
  // placeholder: 'Code goes here...',
  // autofocus: false,
  // disabled: false,
  // indentWithTab: true,
  // tabSize: 2
})

//
const langs = {
  javascript: javascript(),
  json: json(),
  css: css(),
  sql: sql()
}
const extensions = ref<any[]>([])
const setLangExtension = () => {
  extensions.value = props.dark ? [langs[props.lang], oneDark] : [langs[props.lang]]
}
//
const codeValue = ref('')
watchEffect(() => {
  codeValue.value = props.code
  setLangExtension()
  console.log(props.lang)
})

const emits = defineEmits(['update:code', 'ready', 'change', 'focus', 'blur'])
function handleReady(payload: any) {
  // console.log('ready')
  emits('ready', payload)
}
function onChange(value: string, viewUpdate: any) {
  emits('change', value, viewUpdate)
  emits('update:code', value)
}
function onFocus(viewUpdate: any) {
  emits('focus', viewUpdate)
}
function onBlur(viewUpdate: any) {
  emits('blur', viewUpdate)
}
</script>
